package com.test.mybatis.generator;

import io.swagger.annotations.ApiModelProperty;
import org.junit.Test;

import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * @author HelSing
 * @date 2019/3/18
 */
public class CodeCommentGenerator {

  //只需要改动这里;
  private static String database = "japan";
  private static String className = "com.mysql.jdbc.Driver";

  private static String username = "aojiroot";
  private static String password = "Aoji@321.com";

  private static String url = "jdbc:mysql://bj-cdb-lkltxurs.sql.tencentcdb.com:63769/" + database + "?serverTimezone=GMT";
  private static List<String> c = new ArrayList<>();

  private static List<String> template = new ArrayList<>();

  private static List<String> model = new ArrayList<>();

  private static List<String> enums = new ArrayList<>();

  private static String daoPath = System.getProperty("user.dir").indexOf("/") == -1 ?
    System.getProperty("user.dir").replace("\\", "/") : System.getProperty("user.dir");


  static {
    //生成模版
    //c.add("t_construction_pic_group");
    //c.add("t_material_record");
    //c.add("t_suggestion");
    //c.add("t_material");
    //c.add("t_construction_project_log");
    template.add("Controller.text");
    template.add("Service.text");
    //template.add("Manager.text");
    template.add("Mapper.text");
    //c.add("t_design");
    //c.add("m_advertisement");
    //c.add("m_notice");
    //c.add("m_tenant");
    //c.add("m_msg");
    //c.add("m_msg_config");
    //c.add("m_msg_queue");
    //c.add("m_msg_template");
    //c.add("t_activity_info");
    //c.add("t_allocate_apply");
    //c.add("t_apply_list_meterial_deatail");
    //c.add("t_construction_pic_group");
    //c.add("t_construction_project_detail");
    //c.add("t_construction_project_info");
    //c.add("t_custom_info");
    //c.add("t_house");
    //c.add("t_project_ext_status_detail");
    //c.add("t_activity_detail");
    //c.add("t_construction_scheme");
    //c.add("t_damage_apply");
    //c.add("t_custom_info");
    //c.add("t_iutbound_apply");

    //c.add("t_outbound_apply");
//    c.add("t_permission");
    //c.add("t_project_record");
    //c.add("t_purchase_apply");
    //c.add("t_repair_report");
    //c.add("t_return_visit_record");
    c.add("t_voucher");
//    c.add("t_role");
//    c.add("t_role_permission");
//    c.add("t_user");
//    c.add("t_user_role");
//    c.add("t_user_warehouse");
    //c.add("t_warehouse");
    model.add("entity.text");
    model.add("QueryReq.text");
    model.add("QueryResp.text");
    model.add("Req.text");
    model.add("Condition.text");

    //enums.add("Enum.text");

  }

  @Test
  public void run() throws Exception {
    codeDing();
    daoXml();
    model();
    //enumsCode();
  }

  private static void enumsCode() throws Exception {
    List<String> cz = new ArrayList<>();
    Class.forName(className);
    Connection connection = DriverManager.getConnection(url, username, password);
    DatabaseMetaData metaData = connection.getMetaData();

    //获取数据库下面所有表
    ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

    while (tables.next()) {
      // 列的个数
      int columnCount = tables.getMetaData().getColumnCount();
      // 根据指定列名称获取数据
      String TABLE_NAME = tables.getString("TABLE_NAME");
      if (TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
        continue;
      }
      if (cz.contains(TABLE_NAME)) {
        continue;
      }
      if (!c.isEmpty()) {
        if (!c.contains(TABLE_NAME)) {
          continue;
        }
      }
      System.out.println(TABLE_NAME);
      cz.add(TABLE_NAME);
      String tableNames = TABLE_NAME.substring(2);
      String head = convertName(tableNames);
      System.out.println(head);
      String h = head.substring(0, 1);
      for (String t : enums) {
        FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/enums/" + t);
        String str = readFile(inputStream);
        str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
        //获取表的所有列
        ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
        StringBuilder property = new StringBuilder();

        while (columns.next()) {

          String COLUMN_NAME = columns.getString("COLUMN_NAME");
          if (COLUMN_NAME.equals("yn")) {
            continue;
          }
          String REMARKS = columns.getString("REMARKS");
          String enumStr[] = REMARKS.split(" ");

          if (enumStr.length > 1 && REMARKS.contains(":")) {
            property.append("/** start---").append(COLUMN_NAME).append("**/");
            StringBuilder columnsStr = new StringBuilder();
            for (int i = 1, l = enumStr.length; i < l; i++) {
              String s = enumStr[i];
              if (s.trim().equals("") || s.trim().equals("默认")) {
                continue;
              }
              System.out.println(REMARKS);
              String[] d = s.split(":");
              if (d.length > 1) {
                columnsStr.append(COLUMN_NAME.toUpperCase(Locale.ROOT)).append(i).append("(\"");
                columnsStr.append(d[0]).append("\",\"").append(d[1]).append("\"),");
              }

            }
            property.append(columnsStr);

          }
        }
        str = str.replace("${property}", property.substring(0, property.length() - 1) + ";");
        System.out.println(str);
        writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + "Enum.java", "enums");
      }

    }
  }

  private static void model() throws Exception {
    List<String> cz = new ArrayList<>();
    Class.forName(className);
    Connection connection = DriverManager.getConnection(url, username, password);
    DatabaseMetaData metaData = connection.getMetaData();

    //获取数据库下面所有表
    ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

    while (tables.next()) {
      // 列的个数
      int columnCount = tables.getMetaData().getColumnCount();
      // 根据指定列名称获取数据
      String TABLE_NAME = tables.getString("TABLE_NAME");
      if (TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
        continue;
      }
      if (cz.contains(TABLE_NAME)) {
        continue;
      }
      if (!c.isEmpty()) {
        if (!c.contains(TABLE_NAME)) {
          continue;
        }
      }
      System.out.println(TABLE_NAME);
      cz.add(TABLE_NAME);
      String tableNames = TABLE_NAME.substring(2);
      String head = convertName(tableNames);
      System.out.println(head);
      String h = head.substring(0, 1);
      for (String t : model) {
        String[] ff = t.split("\\.");
        FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/model/" + t);
        String str = readFile(inputStream);
        str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
        //获取表的所有列
        ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
        StringBuilder property = new StringBuilder();

        while (columns.next()) {
          String COLUMN_NAME = columns.getString("COLUMN_NAME");
          String COLUMN_NAME_UP = convertName(COLUMN_NAME);
          String TYPE_NAME = columns.getString("TYPE_NAME");

          String REMARKS = columns.getString("REMARKS");
          String types = "String ";
          if (TYPE_NAME.toLowerCase(Locale.ROOT).contains("bigint")) {
            types = "Long ";
          } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("tinyint") || TYPE_NAME.toLowerCase(Locale.ROOT).contains("int")
            || TYPE_NAME.toLowerCase(Locale.ROOT).equals("bit")) {
            types = "Integer ";
          } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("datetime")) {
            types = "Date ";
          } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("decimal")) {
            types = "BigDecimal ";
          }
          if (ff[0].equals("Condition")) {
            if (!COLUMN_NAME_UP.equals("created") && !COLUMN_NAME_UP.equals("createUserId") &&
              !COLUMN_NAME_UP.equals("createUserName") && !COLUMN_NAME_UP.equals("modified") &&
              !COLUMN_NAME_UP.equals("modificationUserId") && !COLUMN_NAME_UP.equals("modificationUserName")
              && !COLUMN_NAME_UP.equals("yn") && !COLUMN_NAME_UP.equals("tenantId")
            ) {
              property.append("    ").append("/** ")
                .append("\r\n")
                .append("    ").append("*").append(" ").append(REMARKS)
                .append("\r\n")
                .append("    ").append("**/")
                .append("\r\n")
                .append("    ").append("private ").append(types).append(COLUMN_NAME_UP).append(";");

            }
          } else {
            property.append("    ").append("/** ")
              .append("\r\n")
              .append("    ").append("*").append(" ").append(REMARKS)
              .append("\r\n")
              .append("    ").append("**/")
              .append("\r\n");
              if (ff[0].equals("Req") || ff[0].equals("QueryReq")) {
                property.append("    ").append("@ApiModelProperty(value = \""+REMARKS+"\")")
                  .append("\r\n");
              }
              property.append("    ").append("private ").append(types).append(COLUMN_NAME_UP).append(";");
          }
          property.append("\r\n");
          property.append("\r\n");
        }
        str = str.replace("${property}", property.toString());
        System.out.println(str);
        String hh = "";
        if (!ff[0].equals("entity")) {
          hh = ff[0];
        }
        writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + hh + ".java", "model");
      }

    }

  }


  public static void codeDing() throws Exception {
    List<String> cz = new ArrayList<>();
    Class.forName(className);
    Connection connection = DriverManager.getConnection(url, username, password);
    DatabaseMetaData metaData = connection.getMetaData();

    //获取数据库下面所有表
    ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

    while (tables.next()) {
      // 列的个数
      int columnCount = tables.getMetaData().getColumnCount();
      // 根据指定列名称获取数据
      String TABLE_NAME = tables.getString("TABLE_NAME");
      String REMARKS = tables.getString("REMARKS");
      if (TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
        continue;
      }
      if (cz.contains(TABLE_NAME)) {
        continue;
      }
      if (!c.isEmpty()) {
        if (!c.contains(TABLE_NAME)) {
          continue;
        }
      }
      System.out.println(TABLE_NAME);
      cz.add(TABLE_NAME);

      String tableNames = TABLE_NAME.substring(2);
      String head = convertName(tableNames);
      System.out.println(head);
      String h = head.substring(0, 1);

      for (String t : template) {
        String[] ff = t.split("\\.");
        FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/template/" + t);
        String str = readFile(inputStream);
        str = str.replace("${table}", head);
        str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
        str = str.replace("${remark}", REMARKS);
        System.out.println(str);
        writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + ff[0] + ".java", ff[0].toLowerCase(Locale.ROOT));
      }
    }

  }

  private static void writeFile(String str, String fileName, String dir) {
    String filePath = daoPath + "/src/test/java/com/test/mybatis/generator/file/" + dir + "/";
    FileWriter fw = null;
    try {

      File file = new File(filePath);
      if (!file.exists()) {
        file.mkdirs();
      }
      File file2 = new File(filePath + fileName);

      if (!file2.exists()) {
        file.createNewFile();
      }
      fw = new FileWriter(filePath + fileName);
      BufferedWriter bw = new BufferedWriter(fw);
      bw.write(str);
      bw.close();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        fw.close();
      } catch (Exception e) {
        e.printStackTrace();
      }

    }
  }

  private static String readFile(FileInputStream inputStream) throws IOException {

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

    StringBuilder returnStr = new StringBuilder();

    String str = null;
    while ((str = bufferedReader.readLine()) != null) {
      returnStr.append(str);
      returnStr.append("\r\n");
    }
    inputStream.close();
    bufferedReader.close();

    return returnStr.toString();
  }

  private static String convertName(String columnName) {
    StringBuilder sb = new StringBuilder();
    String[] str = columnName.split("_");
    sb.append(str[0]);
    for (int i = 1, l = str.length; i < l; i++) {
      String s = str[i];
      sb.append(s.substring(0, 1).toUpperCase(Locale.ROOT));
      sb.append(s.substring(1));
    }
    return sb.toString();
  }

  public static void daoXml() throws Exception {
    List<String> cz = new ArrayList<>();
    Class.forName(className);
    Connection connection = DriverManager.getConnection(url, username, password);
    DatabaseMetaData metaData = connection.getMetaData();

    //获取数据库下面所有表
    ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

    while (tables.next()) {
      // 列的个数
      int columnCount = tables.getMetaData().getColumnCount();
      // 根据指定列名称获取数据
      String TABLE_NAME = tables.getString("TABLE_NAME");
      if (TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
        continue;
      }
      if (cz.contains(TABLE_NAME)) {
        continue;
      }
      if (!c.isEmpty()) {
        if (!c.contains(TABLE_NAME)) {
          continue;
        }
      }

      System.out.println(TABLE_NAME);
      cz.add(TABLE_NAME);
      String tableNames = TABLE_NAME.substring(2);
      String head = convertName(tableNames);
      System.out.println(head);
      String h = head.substring(0, 1);

      FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/xml/dao.text");
      String str = readFile(inputStream);
      str = str.replace("${table}", TABLE_NAME);
      str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
      //获取表的所有列
      ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
      StringBuilder map = new StringBuilder();
      StringBuilder columnSql = new StringBuilder();
      StringBuilder columnInsertSql = new StringBuilder();
      StringBuilder valueSql = new StringBuilder();
      StringBuilder setSql = new StringBuilder();
      StringBuilder setSelective = new StringBuilder();
      StringBuilder selectSelective = new StringBuilder();
      while (columns.next()) {
        String COLUMN_NAME = columns.getString("COLUMN_NAME");
        String COLUMN_NAME_UP = convertName(COLUMN_NAME);
        String TYPE_NAME = columns.getString("TYPE_NAME");
        String p = TYPE_NAME.replace(" UNSIGNED", "");
        if ("DATETIME".equals(TYPE_NAME)) {
          p = "TIMESTAMP";
        } else if (TYPE_NAME.contains("INT")) {
          p = "INTEGER";
        }
        columnSql.append(",`").append(COLUMN_NAME).append("`");
        if (!COLUMN_NAME.equals("id")) {
          columnInsertSql.append(",").append("`").append(COLUMN_NAME).append("`");
        }
        if (COLUMN_NAME.equals("modified") || COLUMN_NAME.equals("created")) {
          valueSql.append(",now()");
        } else if (COLUMN_NAME.equals("yn")) {
          valueSql.append(",1");
        } else if (COLUMN_NAME.equals("id")) {

        } else {
          valueSql.append(",#{").append(COLUMN_NAME_UP).append("}");
        }
        if (!COLUMN_NAME.equals("created")) {
          if (COLUMN_NAME.equals("modified")) {
            setSql.append(",`").append(COLUMN_NAME).append("` = now()");

          } else {
            setSql.append(",`").append(COLUMN_NAME).append("` = #{").append(COLUMN_NAME_UP).append("}");
            if (!COLUMN_NAME_UP.equals("createUserId") && !COLUMN_NAME_UP.equals("createUserName")
              && !COLUMN_NAME_UP.equals("tenantId")&& !COLUMN_NAME_UP.equals("id")) {
              String n = "";
              if (TYPE_NAME.equals("VARCHAR")) {
                n = "and '' != " + COLUMN_NAME_UP;
              }
              String ifsql = "<if test=\""+COLUMN_NAME_UP+" != null "+ n +"\">`"+COLUMN_NAME+"`= #{"+COLUMN_NAME_UP+" ,jdbcType="+p+"},</if>";
              setSelective.append(ifsql);
              if (!COLUMN_NAME.equals("yn") && !COLUMN_NAME_UP.equals("modificationUserId")
                && !COLUMN_NAME_UP.equals("modificationUserName")) {
                String sifsql = "<if test=\"" + COLUMN_NAME_UP + " != null " + n + "\"> and `" + COLUMN_NAME + "`= #{" + COLUMN_NAME_UP + " ,jdbcType=" + p + "}</if>";
                selectSelective.append(sifsql);
              }

            }

          }
        }


        map.append("<result column=\"" + COLUMN_NAME + "\" property=\"" + COLUMN_NAME_UP + "\" jdbcType=\"" + p + "\" />");
        map.append("\r\n");
        map.append("    ");
      }
      setSelective.append("`modified` = now()");

      str = str.replace("${map}", map.toString());
      str = str.replace("${columnSql}", columnSql.substring(1));
      str = str.replace("${columnInsertSql}", columnInsertSql.substring(1));
      str = str.replace("${valueSql}", valueSql.substring(1));
      str = str.replace("${setSql}", setSql.substring(1));
      str = str.replace("${setSelective}", setSelective.toString());
      str = str.replace("${selectSelective}", selectSelective.toString());
      System.out.println(str);
      writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + "Mapper.xml", "xml");
    }

  }
}


